package com.org.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.org.common.PageBean;
import com.org.common.Result;
import com.org.pojo.Serve;
import com.org.pojo.ServeRespond;
import com.org.pojo.Skill;
import com.org.service.ISkillService;
import com.org.service.NormalUserService;
import com.org.service.ServeRespondService;
import com.org.service.ServeService;
import com.org.utils.MapUtil;
import com.org.utils.MatchUtil;
import com.org.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 * 用户技能表 前端控制器
 * </p>
 *
 * @author cjx
 * @since 2024-02-29
 */
@RestController
@RequestMapping("/skill")
public class SkillController {

    @Autowired
    private ISkillService skillService;

    @Autowired
    private ServeService serveService;

    @Autowired
    private NormalUserService normalUserService;

    @Autowired
    private ServeRespondService serveRespondService;

    // 发布
    @PostMapping("/add")
    public Result addSkill(@RequestBody Skill skill) {
        skill.setCreateTime(LocalDateTime.now());
        return skillService.save(skill) ? Result.success(skill) : Result.error("发布技能失败");
    }

    // 删除
    @GetMapping("/delete")
    public Result deleteSkill(long skillId) {
        return skillService.removeById(skillId) ? Result.success() : Result.error("删除技能失败");
    }

    // 查看详情
    @GetMapping("/detail")
    public Result<Skill> getSkillDetail(long skillId, String location) {
        Skill skill = skillService.getById(skillId);
        skill.setDistance(MapUtil.getDistance(skill.getLocation(), location));
        return Result.success(skill);
    }

    // 修改
    @PostMapping("/update")
    public Result updateSkill(@RequestBody Skill skill) {
        skill.setUpdateTime(LocalDateTime.now());
        return skillService.updateById(skill) ? Result.success(skill) : Result.error("修改技能失败");
    }

    /**
     * 修改技能状态修改
     *
     * @param skillId 该修改技能的 id
     * @param state   要修改成的状态
     * @return 是否成功
     */
    @GetMapping("/updateState")
    public Result updateSkillStatus(long skillId, String state) {
        LambdaUpdateWrapper<Skill> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Skill::getId, skillId);
        wrapper.set(Skill::getState, state);
        wrapper.set(Skill::getUpdateTime, LocalDateTime.now());
        return skillService.update(wrapper) ? Result.success() : Result.error("修改技能状态失败");
    }

    // 分页查询
    @GetMapping("/list")
    public Result<PageBean<Skill>> getSkills(
            Integer pageNum,    //第几页
            Integer pageSize,   //页面容量
            String location,    //当前定位
            @RequestParam(required = false) String userId,     //用户id 可为空
            @RequestParam(required = false) String state,      // 状态 可为空
            @RequestParam(required = false) String communityId,  // 社区id 可为空
            @RequestParam(required = false) String type,  // 服务类型 可为空
            @RequestParam(required = false) String sortMethod,  // 排序方式 可为空
            @RequestParam(required = false) String username  // 用户名 可为空
    ) {
        System.out.println(location);

        LambdaQueryWrapper<Skill> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (userId != null && !userId.isEmpty()) {
            lambdaQueryWrapper.eq(Skill::getUserId, userId);
        }
        if (state != null && !state.isEmpty()) {
            lambdaQueryWrapper.eq(Skill::getState, state);
        }
        if (communityId != null && !communityId.isEmpty()) {
            lambdaQueryWrapper.eq(Skill::getCommunityId, communityId);
        }

//        List<Skill> skills = skillService.list(lambdaQueryWrapper);
//        // 进行类型过滤
//        if (type != null && !type.isEmpty()) {
//            Iterator<Skill> iterator = skills.iterator();
//            while (iterator.hasNext()) {
//                Skill skill = iterator.next();
//                List<String> types = new ArrayList<>(Collections.singletonList(skill.getLable01()));
//                if (skill.getLable02() != null){
//                    types.add(skill.getLable02());
//                }
//                if (skill.getLable03() != null){
//                    types.add(skill.getLable03());
//                }
//                if (skill.getLable04() != null){
//                    types.add(skill.getLable04());
//                }
//                if (!types.contains(type)) {
//                    iterator.remove(); // 使用迭代器删除元素
//                }
//            }
//        }

        if (type != null && !type.isEmpty()) {
            lambdaQueryWrapper.eq(Skill::getLable01, type);
            lambdaQueryWrapper.or().eq(Skill::getLable02, type);
            lambdaQueryWrapper.or().eq(Skill::getLable03, type);
            lambdaQueryWrapper.or().eq(Skill::getLable04, type);
        }

        List<Skill> skills = MapUtil.setSkillDistances(skillService.list(lambdaQueryWrapper), location);

        if(username != null && !username.isEmpty()){
            Iterator<Skill> iterator = skills.iterator();
            while (iterator.hasNext()) {
                Skill skill = iterator.next();
                if (!normalUserService.getById(skill.getUserId()).getName().contains(username)) {
                    iterator.remove(); // 使用迭代器删除元素
                }
            }
        }

        // 进行排序
        if (sortMethod != null && !sortMethod.isEmpty()){
            switch (sortMethod){
                case "距离最近":
                    skills.sort((o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance()));
                    break;
                case "开始时间最近":
                    skills.sort((o1, o2) -> o1.getStarttime().compareTo(o2.getStarttime()));
                    break;
                case "最新发布":
                    skills.sort((o1, o2) -> o1.getCreateTime().compareTo(o2.getCreateTime()));
                    break;
            }
        }

        // 分页展示
        int totalSize = skills.size();
        int fromIndex = (pageNum - 1) * pageSize;
        if (fromIndex >= totalSize) {
            PageBean<Skill> pageBean = new PageBean<>();
            pageBean.setTotal(0L);
            pageBean.setItems(new ArrayList<Skill>());
            return Result.success(pageBean); // 返回空列表
        }
        int toIndex = Math.min(fromIndex + pageSize, totalSize);

        PageBean<Skill> pageBean = new PageBean<>();
        pageBean.setTotal((long) totalSize);
        pageBean.setItems(skills.subList(fromIndex, toIndex));

        return Result.success(pageBean);
    }

    /**
     * 老人响应志愿
     * 老人响应 id 为 skillId 的志愿
     * 传入参数示例
     * {
     *      "skillId": 1, 志愿的id
     *      "title": "123", 老人输入的服务的标题
     *      "content": "123", 老人输入的服务的内容
     *      "img01": "123", 老人输入的服务的封面
     *      "duration": 123, 老人输入的时间币
     *      "location": "123", 老人所在经纬度
     *      "address": "123" 老人所在地址
     *      "type": "123" 老人所选的服务类型
     * }
     */
    @PostMapping("/responseSkill")
    public Result responseSkill(@RequestBody Map<String, Object> params) {
        Map<String, Object> param = ThreadLocalUtil.get();
        Integer userId = (Integer) param.get("id");
        // 为老人创建服务
        Serve serve = new Serve();
        serve.setTitle((String)params.get("title"));
        serve.setContent((String)params.get("content"));
        serve.setImg01((String)params.get("img01"));
        serve.setCreateId(userId);
        serve.setCommunityId(normalUserService.getById(userId).getCommunityId());
        serve.setDuration(Double.valueOf(params.get("duration").toString()));
        serve.setNumJoin(1);
        serve.setNumPeople(1);
        Integer skillId = (Integer.valueOf(params.get("skillId").toString()));
        serve.setStartTime(skillService.getById(skillId).getStarttime());
        serve.setEndTime(skillService.getById(skillId).getEndtime());
        serve.setCreateTime(LocalDateTime.now());
        serve.setState("进行中");
        serve.setLocation((String)params.get("location"));
        serve.setAddress((String)params.get("address"));
        serve.setType((String)params.get("type"));
        serveService.save(serve);
        LambdaQueryWrapper<Serve> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(Serve::getId);
        lambdaQueryWrapper.last("limit 1");
        Integer serveId = serveService.getOne(lambdaQueryWrapper).getId();

        // 创建服务响应表
        ServeRespond serveRespond = new ServeRespond();
        serveRespond.setServeId(serveId);
        serveRespond.setUserId(skillService.getById(skillId).getUserId());
        serveRespond.setState("已选择");
        serveRespond.setCreateTime(LocalDateTime.now());
        serveRespondService.save(serveRespond);

        return Result.success();
    }


    /**
     * 志愿者发布技能后与服务匹配
     * @param skillId 技能的id
     * @return 如果最后三个都为false的话，则综合考虑进行匹配，
     * 如果最后三个参数某个参数为 true 的话，则匹配结果优先满足该选项（三个中只能选一个为true）
     */
    @GetMapping("/match")
    public Result<List<Serve>> skillMatchService(
            long skillId,
            String location, // 用户当前的定位信息（经纬度）
            boolean distanceFirst, // 优先匹配距离最近的
            boolean typeFirst, // 优先匹配服务类型相同的
            boolean timeFirst // 优先匹配服务时间段最贴切的
    ) {
        // 当前技能
        Skill skill = skillService.getById(skillId);
        // 技能信息
        List<String> skillTypes = Arrays.asList(skill.getLable01(), skill.getLable02(), skill.getLable03(), skill.getLable04());
        LocalDateTime skillStartTime = skill.getStarttime();
        LocalDateTime skillEndTime = skill.getEndtime();

        // 获取服务列表
        List<Serve> serves = serveService.list(new LambdaQueryWrapper<Serve>()
                .eq(Serve::getState, "已发布")
                .apply("num_people - num_join != 0")
        );

        // 距离优先
        if (distanceFirst){
            // 获取距离
            for (Serve serve : serves){
                double dis = MapUtil.getDistance(location, serve.getLocation());
                serve.setDistance(dis);
            }
            // 排序
            serves.sort((o1, o2)-> Double.compare(o1.getDistance(),o2.getDistance()));
            return Result.success(serves);
        }

        // 类型优先
        if (typeFirst){
            List<Serve> result = new ArrayList<>();
            for (Serve serve : serves){
                if(skillTypes.contains(serve.getType())){
                    result.add(serve);
                }
            }
            return Result.success(MapUtil.setServeDistances(result, location));
        }

        // 时间段优先
        if (timeFirst){
            List<Serve> result = new ArrayList<>();
            for (Serve serve : serves){
                if(skillStartTime.isBefore(serve.getStartTime()) && skillEndTime.isAfter(serve.getEndTime())){
                    result.add(serve);
                }
            }
            return Result.success(MapUtil.setServeDistances(result, location));
        }

        // 按综合分数综合分数
        MapUtil.setServeDistances(serves, location);
        for (Serve serve : serves) {
            double ratio = 1 - serve.getDistance() / 2000 < 0 ? 0 : 1 - serve.getDistance() / 2000;
            double disScore = 30 * ratio;
            serve.setScore(MatchUtil.getScore(skill, serve) + disScore);
        }
        // 排序
        serves.sort((o1, o2) -> Double.compare(o2.getScore(), o1.getScore()));
        return Result.success(serves);
    }

    // 查看自己发布了的志愿的数量
    @GetMapping("/count")
    public Result count(){
        Map<String, Object> param = ThreadLocalUtil.get();
        Integer userId = (Integer) param.get("id");
        Long count = skillService.count(new LambdaQueryWrapper<Skill>().eq(Skill::getUserId, userId));
        return Result.success(count);
    }
}
